#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<assert.h>

#define SEP " "
#define NUM 256
#define SIZE 32

#define NONE_REDIR 0
#define INPUT_REDIR 1
#define OUT_REDIR 2
#define APPEND_REDIR 3


char buffer[64];
char cd_line[NUM];
char* cd_args[SIZE];


int redir_status = NONE_REDIR;

char* CheckRedir(char* start)
{
    assert(start);

    char* end = start+strlen(start)-1;
    while(end>=start)
    {
        if(*end=='>')
        {
            if(*(end-1)=='>')
            {
                *(end-1)='\0';
                redir_status = APPEND_REDIR;
                end =end+1;
                break;
            }
            
            *end = '\0';
            redir_status = OUT_REDIR;
            end++;
            break;
        }
        else if(*end=='<')
        {
            *end='\0';
            redir_status = INPUT_REDIR;
            end++;
            break;
        }
        else{
            end--;
        }
    }
    
    if(end>=start)
    {
        return end;
    }
    else{
        return NULL;
    }


}


int main()
{
    while(1)
    {
        printf("[shell @test ] # ");
        fflush(stdout);
        memset(cd_line,NUM,'\0');
        if( fgets(cd_line,sizeof cd_line,stdin)==NULL)
            continue;

        cd_line[strlen(cd_line)-1] = '\0';
        
        char* sep = CheckRedir(cd_line);


        int index = 0;
        cd_args[index++] = strtok(cd_line,SEP);
        if(strcmp(cd_args[0],"ls")==0)
        {
            cd_args[index++] =(char*)"--color=auto";
        }
        if(!strcmp(cd_args[0],"ll"))
        {
            cd_args[0] ="ls";
            cd_args[index++]="-l";
            cd_args[index++]="--color=auto";
        }
        while(cd_args[index++] = strtok(NULL,SEP));

        
        if(!strcmp(cd_args[0],"export")&&cd_args[1]!=NULL)
        {
            strcpy(buffer,cd_args[1]);
            putenv(buffer);

            continue;
        }

        //for(int i = 0;cd_args[i];i++)
        //{
        //    printf("%s\n",cd_args[i]);
        //}

        if(strcmp(cd_args[0],"cd")==0)
        {
            if(cd_args[1]!=NULL)
                chdir(cd_args[1]);
            continue;
        }
        
        

        pid_t id = fork();
        if(id==0)
        {
            if(sep!=NULL)
            {
                int fd =-1;
                switch(redir_status)
                {
                    case INPUT_REDIR:
                        fd = open(sep,O_RDONLY);
                        dup2(fd,0);
                        break;
                    case OUT_REDIR:
                        fd = open(sep,O_WRONLY | O_TRUNC |O_CREAT,0666);
                        dup2(fd,1);
                        break;
                    case APPEND_REDIR:
                        fd=open(sep,O_WRONLY | O_APPEND |O_CREAT,0666);
                        dup2(fd,1);
                        break;
                    default:
                        printf("bug?\n");
                        break;
                }
            }
            printf("子进程执行：\n");
            execvp(cd_args[0],cd_args);
            exit(1);
        }

        int status = 0;
        pid_t res = waitpid(-1,&status,0);
        if(res>0)
            printf("等待成功，结束码为：%d\n",WEXITSTATUS(status));
    }
    return 0;
}
